package com.eveinfo.display.planner;

import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Set;

import com.eveinfo.EveInfo;
import com.eveinfo.api.utils.skilllist.ApiRequirement;
import com.eveinfo.api.utils.skilllist.ApiSkill;
import com.eveinfo.api.utils.skilllist.ApiSkills;
import com.eveinfo.tools.Tools;

public class Planner implements Serializable {

	private static final long serialVersionUID = 5740486471659011717L;

	private final String name;
	private final LinkedList<TaskPlanner> tasks;
	private final int characterID;
	
	private int id;
	private double time;
	
	public Planner(String name, int characterID) {
		this.id = 0;
		this.time = 0;
		this.name = name;
		this.tasks = new LinkedList<TaskPlanner>();
		this.characterID = characterID;
	}

	private void addTask(TaskPlanner task, int position) {
		time += task.getTrainingTime();
		if (position == -1) {
			tasks.addLast(task);
			return;
		}
		if (position == 0) {
			tasks.addFirst(task);
			return;
		}
		tasks.add(position, task);
	}

	public boolean containTask(int skillId, int level) {
		for (TaskPlanner task : tasks) {
			if (task.getSkillID() == skillId && task.getSkillLevel() == level)
				return true;
		}
		return false;
	}

	public TaskPlanner getTask(int skillId, int level) {
		for (TaskPlanner task : tasks) {
			if (task.getSkillID() == skillId && task.getSkillLevel() == level)
				return task;
		}
		return null;
	}

	public TaskPlanner getTaskWithID(int id) {
		for (TaskPlanner task : tasks) {
			if (task.getId() == id)
				return task;
		}
		return null;
	}

	public int getNewID() {
		if (Integer.MAX_VALUE == id) {
			return 0;
		}
		return ++id;
	}

	public void addSkill(ApiSkill skill, int level, int position, boolean checkPrerequired, int parentID) {
		if (level == 0)
			return;
		TaskPlanner taskInPlanner = getTask(skill.getTypeID(), level);
		if (taskInPlanner != null) {
			taskInPlanner.addDependence(parentID);
			return;
		}
		ApiSkills allSkill = EveInfo.getData().getSkills();
		double timeToLevel = Tools.getTimeToLevel(characterID, allSkill, skill, level, false);
		if (timeToLevel == 0) {
			return;
		}
		int newID = getNewID();
		if (checkPrerequired && level == 1) {
			Collection<ApiRequirement> requiredSkills = skill.getRequiredSkills();
			for (ApiRequirement requirement : requiredSkills) {
				ApiSkill skillRequired = allSkill.getSkill(requirement.getTypeID());
				addSkill(skillRequired, requirement.getSkillLevel(), position, true, newID);
			}
		}
		if (checkPrerequired) {
			addSkill(skill, level - 1, position, true, newID);
		}
		TaskPlanner task = new TaskPlanner(newID, skill.getTypeID(), skill.getTypeName(), level, timeToLevel);
		if (parentID != -1) {
			task.addDependence(parentID);
		}
		addTask(task, position);

	}

	public void addSkill(int skillID, int level, int position) {
		ApiSkill skill = EveInfo.getData().getSkills().getSkill(skillID);
		addSkill(skill, level, position, true, -1);
	}

	public void addSkill(int skillID, int level) {
		ApiSkill skill = EveInfo.getData().getSkills().getSkill(skillID);
		addSkill(skill, level, -1, true, -1);
	}

	public void addSkill(ApiSkill skill, int level) {
		addSkill(skill, level, -1, true, -1);
	}

	public int getSize() {
		return tasks.size();
	}

	public TaskPlanner getTask(int position) {
		return tasks.get(position);
	}

	public void removeSkill(int id) {
		TaskPlanner task = getTaskWithID(id);
		if (task == null) {
			return;
		}
		time -= task.getTrainingTime();
		tasks.remove(task);
		Set<Integer> dependences = task.getDependences();
		for (int i : dependences) {
			removeSkill(i);
		}
	}

	public String getName() {
		return name;
	}

	public double getTime() {
		return time;
	}
}
